package com.kinyx.framework.tree;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.function.Function;

import com.kinyx.framework.Configs;
import com.kinyx.framework.annotation.assist.CanNotNull;
import com.kinyx.framework.annotation.assist.CanNull;
import com.kinyx.framework.annotation.assist.ReturnNull;
import com.kinyx.framework.bean.TreeNode;
import com.kinyx.framework.utils.KListUtils;

import lombok.AccessLevel;
import lombok.NoArgsConstructor;

/**
 * 树形结构工具类
 */
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public final class KTreeUtils {

	/**
	 * 增加子节点
	 * @param list 列表对象
	 * @param parent 上级节点
	 */
	private static void addChild(@CanNotNull final List<TreeNode> list, @CanNotNull final TreeNode parent) {
		for (final TreeNode child : list) {
			if (parent.getCode().equals(child.getParentCode())) {
				parent.addChild(child);
				addChild(list, child);
			}
		}
	}

	/**
	 * 转换为树形结构
	 * @param list 列表对象
	 * @return 树形结构
	 */
	@ReturnNull("list == null")
	public static List<TreeNode> toTree(@CanNull final List<TreeNode> list) {
		if (list == null) { return null; }
		if (list.isEmpty()) { return Collections.emptyList(); }
		final List<TreeNode> listRoot = new ArrayList<>();
		Collections.sort(list, (o1, o2) -> o1.getCode().compareTo(o2.getCode()));
		for (final TreeNode bean : list) {
			if (bean.getParentCode().equals(Configs.ROOT)) {
				listRoot.add(bean);
				addChild(list, bean);
			}
		}
		return listRoot;
	}

	/**
	 * 转换为树形结构
	 * @param <Source> 泛型
	 * @param list 列表对象
	 * @param converter 转换器
	 * @return 树形结构
	 */
	@ReturnNull("list == null")
	public static <Source> List<TreeNode> toTree(@CanNotNull final List<Source> list, @CanNotNull final Function<Source, TreeNode> converter) {
		return toTree(KListUtils.convert(list, converter));
	}

}
